package com.pgytesting.mobilecertpay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.pgytesting.mobilecertpay.dao.NaCaptchaInformationDao;
import com.pgytesting.mobilecertpay.dao.NaUserInfoDao;
import com.pgytesting.mobilecertpay.entity.NaCaptchaInformation;
import com.pgytesting.mobilecertpay.entity.NaOrderInformation;
import com.pgytesting.mobilecertpay.dao.NaOrderInformationDao;
import com.pgytesting.mobilecertpay.entity.NaUserInfo;
import com.pgytesting.mobilecertpay.service.NaOrderInformationService;
import com.pgytesting.mobilecertpay.util.FaceIDCread;
import com.pgytesting.mobilecertpay.util.ResponseMassage;
import com.pgytesting.mobilecertpay.util.UtilMethod;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单信息表(NaOrderInformation)表服务实现类
 *
 * @author makejava
 * @since 2019-05-10 10:22:59
 */
@Slf4j
@Service("naOrderInformationService")
public class NaOrderInformationServiceImpl implements NaOrderInformationService {
    @Resource
    private NaOrderInformationDao naOrderInformationDao;

    @Resource
    private NaUserInfoDao naUserInfoDao;

    @Resource
    private NaCaptchaInformationDao naCaptchaInformationDao;


    private static final Long TEN_MINUTES = 600000L;


    /**
     * 通过ID查询单条数据
     *
     * @param jsonObject json对象
     * @return 实例对象
     */
    @Override
    public Map<String, Object> queryById(JSONObject jsonObject) {
        log.info("进行参数获取");
        NaOrderInformation naOrderInformation = this.naOrderInformationDao.queryById(jsonObject.getString("outOrderId"));
        Map<String,Object> resultMap = new LinkedHashMap<>();
        log.info("订单信息获取成功，进行返回参数拼接");
        resultMap.put("orderStatus",naOrderInformation.getOrderStatus());
        resultMap.put("outOrderId",naOrderInformation.getOutOrderId());
        resultMap.put("merchantId",naOrderInformation.getMerchantId());
        return resultMap;
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<NaOrderInformation> queryAllByLimit(int offset, int limit) {
        return this.naOrderInformationDao.queryAllByLimit(offset, limit);
    }

    /**
     * 条件查询多条数据
     *
     * @param naOrderInformation 实例对象
     * @return 对象列表
     */
    @Override
    public List<NaOrderInformation> queryAll(NaOrderInformation naOrderInformation) {
        return this.naOrderInformationDao.queryAll(naOrderInformation);
    }

    /**
     * 新增数据
     *
     * @param jsonObject json对象
     * @return 实例对象
     */
    @Override
    public Map<String, Object> insert(JSONObject jsonObject) {
        NaOrderInformation naOrderInformation = new NaOrderInformation();
        log.info("进行订单信息参数转化");
        //订单号
        naOrderInformation.setOutOrderId(UtilMethod.getUniqueCode());
        //商户号
        naOrderInformation.setMerchantId(jsonObject.getString("merchantId"));
        //用户ID   uuid进行MD5加密
        naOrderInformation.setUserId(UtilMethod.md5Encryption(UtilMethod.getUniqueCode()));
        //交易银行卡号
        naOrderInformation.setBankCardNo(jsonObject.getString("bankCardNo"));
        //金额
        Double  amount = Double.valueOf(jsonObject.getString("amount"));
        naOrderInformation.setAmount(amount);
        //交易时间
        naOrderInformation.setTradeTime(UtilMethod.unixLong());
        //订单状态  -- 订单为未支付状态
        naOrderInformation.setOrderStatus("03");
        log.info("进行用户信息提取");
        NaUserInfo naUserInfo = new NaUserInfo();
        //用户ID
        naUserInfo.setUserId(naOrderInformation.getUserId());
        //手机号
        naUserInfo.setMobileNo(jsonObject.getString("mobileNo"));
        //姓名
        String userName = jsonObject.getString("realName");
        naUserInfo.setRealName(userName);
        //身份证
        naUserInfo.setCardNo(jsonObject.getString("cardNo"));
        //身份证正面
        naUserInfo.setIdCardFront(jsonObject.getString("IdCardFront"));
        //身份证反面
        naUserInfo.setIdCardNegative(jsonObject.getString("IdCardNegative"));
        //回调地址
//        naUserInfo.setNoticeUrl(jsonObject.getString("noticeUrl"));
        //用户邮箱
        naUserInfo.setMerchantMail(jsonObject.getString("merchantMail"));
        log.info("进行身份证信息验证");
        Map ideInformation = FaceIDCread.getFaceIDCread(naUserInfo.getIdCardFront());
        String idCardNumber = String.valueOf(ideInformation.get("id_card_number"));
        String name = String.valueOf(ideInformation.get("name"));
        if (!idCardNumber.equals(naUserInfo.getCardNo()) && !name.equals(naUserInfo.getRealName())){
            log.info("身份证信息验证未通过");
            return ResponseMassage.getResMassage("00024");
        }
        log.info("进行支付验证码生成");
        NaCaptchaInformation naCapt = new NaCaptchaInformation();
        // 关联邮箱
        naCapt.setMerchantMail(jsonObject.getString("merchantMail"));
        // 验证码类型 --- 关联订单号
        naCapt.setCaptchaType(naOrderInformation.getOutOrderId());
        // 获取时间
        naCapt.setCurrentTime(UtilMethod.unixLong());
        // 验证码
        naCapt.setMailCode(UtilMethod.randomCode());
        // 获取次数
        naCapt.setNumberTimes(1);
        log.info("进行用户信息核查");
        Map<String,Object> resultMap = new LinkedHashMap<>();
        NaUserInfo naUser = naUserInfoDao.queryById(naUserInfo);
        if (naUser == null){
            try {
                naUserInfoDao.insert(naUserInfo);
            }catch (Exception e){
                log.error("用户数据插入失败" + e.getMessage());
                return ResponseMassage.getResMassage("20003");
            }
            try {
                log.info("支付订单信息插入");
                this.naOrderInformationDao.insert(naOrderInformation);
            } catch (Exception e) {
                log.error("预支付数据插入失败,进行用户数据回溯");
                log.error(e.getMessage());
                naUserInfoDao.deleteById(naUserInfo.getUserId());
                return ResponseMassage.getResMassage("20003");
            }
            try {
                log.info("支付订单信息验证码插入");
                naCaptchaInformationDao.insert(naCapt);
            } catch (Exception e) {
                log.error("支付订单信息验证码插入失败,进行用户数据回溯");
                log.error(e.getMessage());
                naUserInfoDao.deleteById(naUserInfo.getUserId());
                naOrderInformationDao.deleteById(naOrderInformation.getOutOrderId());
                return ResponseMassage.getResMassage("20003");
            }
            resultMap.put("outOrderId",naOrderInformation.getOutOrderId());
            resultMap.put("respCode","00");
            resultMap.put("respMsg","尊敬的用户 "
                    + userName
                    + " 您好：\n\t您有一份金额为："
                    + amount
                    + "元的新的订单："
                    + naOrderInformation.getOutOrderId()
                    + " 正在支付中。\n您的确认支付验证码为："
                    + naCapt.getMailCode()
                    + "，有效时间10分钟，请尽快完成支付");
            return resultMap;
        }
        try {
            log.info("支付订单信息");
            naOrderInformation.setUserId(naUser.getUserId());
            this.naOrderInformationDao.insert(naOrderInformation);
        } catch (Exception e) {
            log.error("预支付数据插入失败" + e.getMessage());
            return ResponseMassage.getResMassage("20003");
        }
        try {
            log.info("支付订单信息验证码插入");
            naCaptchaInformationDao.insert(naCapt);
        } catch (Exception e) {
            log.error("支付订单信息验证码插入失败,进行用户数据回溯");
            log.error(e.getMessage());
            naOrderInformationDao.deleteById(naOrderInformation.getOutOrderId());
            return ResponseMassage.getResMassage("20003");
        }
        resultMap.put("respCode","00");
        resultMap.put("outOrderId",naOrderInformation.getOutOrderId());
        resultMap.put("respMsg","尊敬的用户 "
                + userName
                + " 您好：\n\t您有一份金额为："
                + amount
                + "元的新的订单："
                + naOrderInformation.getOutOrderId()
                + " 正在支付中。\n您的确认支付验证码为："
                + naCapt.getMailCode()
                + "，有效时间10分钟，请尽快完成支付");
        return resultMap;
    }

    /**
     * 修改数据
     *
     * @param jsonObject json对象
     * @return 实例对象
     */
    @Override
    public Map<String, Object> update(JSONObject jsonObject) {
        log.info("获取确认支付参数");
        // 支付验证码对象
        NaCaptchaInformation naCapt = new NaCaptchaInformation();
        // 验证码类型  ---订单号
        naCapt.setCaptchaType(jsonObject.getString("outOrderId"));
        log.info("进行订单信息查询");
        NaOrderInformation naOrderInformation = naOrderInformationDao.queryById(jsonObject.getString("outOrderId"));
        if (naOrderInformation == null){
            return ResponseMassage.getResMassage("10009");
        }
        if ("00".equals(naOrderInformation.getOrderStatus())){
            return ResponseMassage.getResMassage("00086");
        }
        // 进行关联邮箱查询
        NaUserInfo naUserInfo = new NaUserInfo();
        // 进行用户ID关联,查询用户信息
        naUserInfo.setUserId(naOrderInformation.getUserId());
        naUserInfo = this.naUserInfoDao.queryById(naUserInfo);
        // 邮箱
        naCapt.setMerchantMail(naUserInfo.getMerchantMail());
        log.info("进行邮箱验证码查询");
        naCapt = this.naCaptchaInformationDao.queryById(naCapt);
        if (naCapt == null){
            return ResponseMassage.getResMassage("00082");
        }
        if (!jsonObject.getString("mailCode").equals(naCapt.getMailCode())){
            return ResponseMassage.getResMassage("20008");
        }
        // 进行验证码有效时间验证
        if ((naCapt.getCurrentTime() + TEN_MINUTES) < UtilMethod.unixLong()){
            log.info("验证码过期，请重新获取");
            return ResponseMassage.getResMassage("20009");
        }
        log.info("信息核验完成进行订单确认支付更新");
        try {
            naOrderInformation.setOrderStatus("00");
            this.naOrderInformationDao.update(naOrderInformation);
        }catch (Exception e){
            log.error("信息核验完成进行订单确认支付更新失败");
            log.error(e.getMessage());
            return ResponseMassage.getResMassage("20003");
        }
        Map<String,Object> resultMap = new LinkedHashMap<>();
        resultMap.put("orderStatus","S");
        resultMap.put("outOrderId",jsonObject.getString("outOrderId"));
        resultMap.put("realName",naUserInfo.getRealName());
        resultMap.put("amount",naOrderInformation.getAmount());
        resultMap.put("tradeTime",naOrderInformation.getTradeTime());
        resultMap.put("merchantMail",naUserInfo.getMerchantMail());
        resultMap.put("respCode","00");
        return resultMap;
    }

    /**
     * 通过主键删除数据
     *
     * @param outOrderId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String outOrderId) {
        return this.naOrderInformationDao.deleteById(outOrderId) > 0;
    }
}